package com.yuantong.xyerp.rest.controller;

import com.yuantong.xyerp.core.api.enums.EnumMsgCode;
import com.yuantong.xyerp.core.api.exception.YuantongException;
import com.yuantong.xyerp.core.api.form.UserLoginParam;
import com.yuantong.xyerp.core.api.model.User;
import com.yuantong.xyerp.core.api.model.base.RestResponseModel;
import com.yuantong.xyerp.core.api.common.Constant;
import com.yuantong.xyerp.core.api.service.IUserService;
import com.yuantong.xyerp.core.api.util.AesCipherUtil;
import com.yuantong.xyerp.core.api.model.UserDetail;
import com.yuantong.xyerp.rest.config.shiro.jwt.JwtIgnore;
import com.yuantong.xyerp.rest.config.shiro.jwt.JwtUtil;
import com.yuantong.xyerp.rest.controller.base.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * Created by Jianguo.Yin on 2021-07-07.
 */
@Api(tags = "用户登录接口")
@Slf4j
@RestController
@RequestMapping("/api")
public class UserController extends BaseController {

    @Resource
    private IUserService userService;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;


    @JwtIgnore
    @PostMapping(value = "/loginByName",produces = "application/json; charset=utf-8")
    @ApiOperation(value = "登录之后返回token",httpMethod = "POST")
    public RestResponseModel<Map<String,Object>> login(@RequestBody
                                           @ApiParam("用户登录参数")
                                           UserLoginParam userLoginParam,
                                        HttpServletResponse httpServletResponse){
        // 查询数据库中的帐号信息
        UserDetail userDetail = new UserDetail();
        userDetail.setLoginName(userLoginParam.getLoginName());
        userDetail = userService.selectOneByUserDetail(userDetail);
        if (userDetail == null) {
            throw new YuantongException(EnumMsgCode.USER_NOT_EXIST);
        }
        // 密码进行AES解密
        String key = AesCipherUtil.deCrypto(userDetail.getPassword());
        // 密码对比
        if (key.equals(userLoginParam.getPassword())) {
            if (userDetail.getStatus().equals(Constant.UN_USEING))
                throw new YuantongException(EnumMsgCode.USER_ACCOUNT_FORBIDDEN);

            String token = JwtUtil.createToken(userDetail.getLoginName(),userDetail.getPassword().hashCode());
            httpServletResponse.setHeader(Constant.Header_Authorization, token);
            httpServletResponse.setHeader(Constant.Header_Access_Control_Expose_Headers, Constant.Header_Authorization);
            /** userDetail存放角色和权限  */
            redisTemplate.opsForValue()
                    .set(Constant.PREFIX_USER_CACHE + userDetail.getLoginName(), userDetail, Constant.USER_EXPIRE_TIME, TimeUnit.SECONDS);

            HashMap<String, Object> detailMap = new HashMap<>();
            detailMap.put("userDetail", userDetail);
            detailMap.put("token", token);
            log.info("(刚登录后)Authorization: Bearer " + token);
            return RestResponseModel.SUCCESS(EnumMsgCode.MSG_SUCCESS, detailMap);
        } else {
            throw new YuantongException(EnumMsgCode.USER_LOGIN_ERROR);
        }
    }
    @PostMapping(value = "/modify_pwd",produces = "application/json; charset=utf-8")
    @ApiOperation(value = "修改密码",httpMethod = "POST")
    public RestResponseModel<String> changePas(@RequestBody @ApiParam("用户登录参数") UserLoginParam userLoginParam,
                                               HttpServletRequest httpServletRequest,
                                               HttpServletResponse httpServletResponse){
        UserDetail userDetail = new UserDetail().setLoginName(userLoginParam.getLoginName());
        // 旧
        userDetail = userService.selectOneByUserDetail(userDetail);
        String key = AesCipherUtil.deCrypto(userDetail.getPassword());
        if (!key.equals(userLoginParam.getPassword()))
            throw new YuantongException(EnumMsgCode.USER_LOGIN_ERROR);
        if (userDetail.getStatus().equals(Constant.UN_USEING))
            throw new YuantongException(EnumMsgCode.USER_ACCOUNT_FORBIDDEN);
        User user = new User()
                .setId(userDetail.getId())
                .setPassword(AesCipherUtil.enCrypto(userLoginParam.getNewPassword()));
        userService.update(user);

        /** 不用加, 改了密码后 旧token必然通不过验证 */
        // // 将旧token加入黑名单
        // String token = getToken(httpServletRequest);
        // redisTemplate.opsForValue().set(Constant.PREFIX_FORBID_TOKEN_CACHE + token, token,  Constant.TOKE_EXPIRE_TIME, TimeUnit.SECONDS);
        //
        // token = JwtUtil.createToken(userDetail.getLoginName(), userDetail.getPassword().hashCode());
        // httpServletResponse.setHeader(Constant.Header_Authorization, token);
        // httpServletResponse.setHeader(Constant.Header_Access_Control_Expose_Headers, Constant.Header_Authorization);

        // 新
        userDetail = userService.selectOneByUserDetail(userDetail);
        // 更新缓存
        redisTemplate.opsForValue().set(Constant.PREFIX_USER_CACHE + userDetail.getLoginName(), userDetail, Constant.USER_EXPIRE_TIME, TimeUnit.SECONDS);

        return RestResponseModel.SUCCESS(EnumMsgCode.MSG_SUCCESS,"修改成功");
    }

    // 重置的是别人的密码
    @PostMapping(value = "/reset_pwd",produces = "application/json; charset=utf-8")
    @ApiOperation(value = "重置密码",httpMethod = "POST")
    public RestResponseModel<String> resetPas(@RequestBody @ApiParam("用户登录参数") UserLoginParam userLoginParam,
                                               HttpServletResponse httpServletResponse,
                                               HttpServletRequest httpServletRequest){
        UserDetail userDetail = new UserDetail().setLoginName(userLoginParam.getLoginName());
        userDetail.setPassword(AesCipherUtil.enCrypto(Constant.DEFAULT_PWD));
        User user = new User()
                .setId(userDetail.getId())
                .setPassword(userDetail.getPassword());
        userService.update(user);

        // 更新缓存
        redisTemplate.opsForValue().set(Constant.PREFIX_USER_CACHE + userDetail.getLoginName(), userDetail, Constant.USER_EXPIRE_TIME, TimeUnit.SECONDS);
        return RestResponseModel.SUCCESS(EnumMsgCode.MSG_SUCCESS,"修改成功");
    }

}
